"use strict";
cc._RF.push(module, '02a22zuhH5B5IgF4IwvCR8E', 'WebSocketTool');
// scripts/net/WebSocketTool.ts

"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebSocketTool = exports.WebSocketToolState = void 0;
var MessageBaseBean_1 = require("./MessageBaseBean");
var MessageId_1 = require("./MessageId");
var Tools_1 = require("../util/Tools");
var Singleton_1 = require("../../meshTools/Singleton");
var EventCenter_1 = require("../common/EventCenter");
var GameMgr_1 = require("../common/GameMgr");
var WebSocketToolState;
(function (WebSocketToolState) {
    WebSocketToolState["Connecting"] = "connecting";
    WebSocketToolState["Connected"] = "connected";
    WebSocketToolState["Closing"] = "closing";
    WebSocketToolState["Reconnecting"] = "reconnecting";
    WebSocketToolState["Timeout"] = "Timeout";
})(WebSocketToolState = exports.WebSocketToolState || (exports.WebSocketToolState = {}));
var WebSocketTool = /** @class */ (function (_super) {
    __extends(WebSocketTool, _super);
    function WebSocketTool() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.webState = WebSocketToolState.Closing; //默认是关闭的
        _this.reconnectInterval = 5000; // 重连间隔，单位毫秒
        _this.heartbeatInterval = 5000; // 心跳间隔，单位毫秒
        _this.heartbeatTimer = null; //心跳定时器的 id
        _this.reconnectMaxCount = 5; // 最大重连次数
        _this.reconnectCount = 0; // 当前重连次数
        _this.heartTimeOutTimer = null; //心跳超时定时器 id
        _this.heartTimeOutInterval = 11000; //心跳超时间隔，单位毫秒
        _this.msgFunction = null; //这个是回调消息的的
        _this.stateFunction = null; //这个是回调 socket 状态的
        return _this;
    }
    WebSocketTool.prototype.setSocketFunction = function (msgFunction, stateFunction) {
        this.msgFunction = msgFunction;
        this.stateFunction = stateFunction;
    };
    //连接
    WebSocketTool.prototype.connect = function () {
        var _this = this;
        this.activeShutdown = false;
        if (this.webState == WebSocketToolState.Connecting || this.webState == WebSocketToolState.Connected)
            return;
        var url = GameMgr_1.GameMgr.GameData.ServerUrl;
        this.setWebState(WebSocketToolState.Connecting);
        this.ws = new WebSocket(url);
        GameMgr_1.GameMgr.Console.Log('webSocket 链接地址' + url);
        //连接成功
        this.ws.onopen = function () {
            _this.setWebState(WebSocketToolState.Connected);
            // 连接成功后发送心跳包
            _this.sendHeartbeat();
            _this.sendHeartTimeOut();
            _this.reconnectCount = 0; //连接上之后 重置重连次数
        };
        //收到消息
        this.ws.onmessage = function (event) {
            // 处理接收到的消息
            GameMgr_1.GameMgr.Console.Log("webSocket \u6536\u5230\u6D88\u606F(" + Tools_1.Tools.getCurrentTimeWithMilliseconds() + "):" + event.data);
            var parsedData = JSON.parse(event.data);
            if (parsedData.msgId == MessageId_1.MessageId.MsgTypeHeartbeat) {
                _this.sendHeartTimeOut();
            }
            if (_this.msgFunction) {
                _this.msgFunction(event.data);
            }
        };
        //关闭连接
        this.ws.onclose = function () {
            if (_this.webState == WebSocketToolState.Reconnecting) {
                //在 ios 系统中 断网不会断开 websocket，所以在这状态下收到的 链接关闭都是上一个的
                console.error('WebSocket error:', '旧链接关闭');
                return;
            }
            console.error('WebSocket error:', '连接关闭');
            _this.setWebState(WebSocketToolState.Closing);
            _this.linkException();
        };
        //连接异常
        this.ws.onerror = function (event) {
            console.error('WebSocket error:', event);
        };
    };
    //主动断开连接
    WebSocketTool.prototype.disconnect = function () {
        console.error('WebSocket error:', '主动断开');
        this.activeShutdown = true;
        this.ws.close();
    };
    //重连，内部自动调用的
    WebSocketTool.prototype.reconnect = function () {
        var _this = this;
        if (this.webState == WebSocketToolState.Reconnecting || this.webState == WebSocketToolState.Connecting)
            return;
        if (this.reconnectCount >= this.reconnectMaxCount) {
            console.error('WebSocket 重连失败');
            var autoMessageBean = {
                'msgId': MessageBaseBean_1.AutoMessageId.ReconnectionFailureMsg,
                'data': {}
            };
            GameMgr_1.GameMgr.Event.Send(EventCenter_1.EventType.AutoMessage, autoMessageBean);
            return;
        }
        this.reconnectCount++;
        this.setWebState(WebSocketToolState.Reconnecting);
        // 重连间隔后重新连接
        setTimeout(function () {
            _this.connect();
        }, this.reconnectInterval);
    };
    //给外部调用的马上重连
    WebSocketTool.prototype.atOnceReconnect = function () {
        this.connect();
    };
    //启动心跳
    WebSocketTool.prototype.sendHeartbeat = function () {
        var _this = this;
        if (this.webState != WebSocketToolState.Connected)
            return;
        var sendMessageBean = {
            msgId: MessageId_1.MessageId.MsgTypeHeartbeat,
            data: {},
        };
        var jsonString = JSON.stringify(sendMessageBean);
        // 发送心跳包
        this.send(jsonString);
        // 每隔心跳间隔发送一次心跳包
        this.heartbeatTimer = setTimeout(function () {
            _this.sendHeartbeat();
        }, this.heartbeatInterval);
    };
    WebSocketTool.prototype.sendHeartTimeOut = function () {
        var _this = this;
        this.stopHeartTime();
        this.heartTimeOutTimer = setTimeout(function () {
            if (_this.webState == WebSocketToolState.Connected) {
                console.error('WebSocket 连接超时');
                _this.setWebState(WebSocketToolState.Timeout);
                console.error('WebSocket 连接超时  强制关闭长链接');
                _this.ws.close(); // Todo 强制关闭一下长链接，不然ios断网不会断开
                _this.linkException();
            }
        }, this.heartTimeOutInterval); // 11 秒心跳超时
    };
    //链接异常
    WebSocketTool.prototype.linkException = function () {
        this.stopHeartbeat();
        this.stopHeartTime();
        if (!this.activeShutdown) {
            var autoMessageBean = {
                'msgId': MessageBaseBean_1.AutoMessageId.LinkExceptionMsg,
                'data': {}
            };
            GameMgr_1.GameMgr.Event.Send(EventCenter_1.EventType.AutoMessage, autoMessageBean);
            // 连接关闭后尝试重连
            this.reconnect();
        }
    };
    //停止心跳
    WebSocketTool.prototype.stopHeartbeat = function () {
        if (this.heartbeatTimer) {
            // 清除心跳定时器
            clearTimeout(this.heartbeatTimer);
            this.heartbeatTimer = null;
        }
    };
    //停止超时监听
    WebSocketTool.prototype.stopHeartTime = function () {
        if (this.heartTimeOutTimer) {
            clearTimeout(this.heartTimeOutTimer);
            this.heartTimeOutTimer = null;
        }
    };
    //发送消息
    WebSocketTool.prototype.send = function (message) {
        GameMgr_1.GameMgr.Console.Log("webSocket \u53D1\u9001\u6D88\u606F(" + Tools_1.Tools.getCurrentTimeWithMilliseconds() + "):" + message);
        if (this.webState == WebSocketToolState.Connected) {
            this.ws.send(message);
        }
        else {
            GameMgr_1.GameMgr.Console.Error('WebSocket is not connected');
        }
    };
    //赋值 websocket 状态
    WebSocketTool.prototype.setWebState = function (webState) {
        this.webState = webState;
        this.stateFunction(webState);
    };
    WebSocketTool.prototype.onDestroy = function () {
        // 清除心跳定时器
        this.stopHeartbeat();
        this.stopHeartTime();
    };
    return WebSocketTool;
}(Singleton_1.Singleton));
exports.WebSocketTool = WebSocketTool;

cc._RF.pop();